from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from django.db.models import Q, Count
from django.utils import timezone
from django.db.models.functions import TruncDate
from datetime import datetime, timedelta
from system.models import Log
from .logs_serializers import LogPageSerializer


class LogPageView(APIView):
    """日志分页列表视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    def get(self, request, *args, **kwargs):
        """
        获取日志分页列表
        
        查询参数:
        - keywords: 关键字(日志内容/请求路径/请求方法/地区/浏览器/终端系统)（可选）
        - createTime: 操作时间范围（可选）
        - pageNum: 页码（必需）
        - pageSize: 每页记录数（必需）
        """
        # 获取查询参数
        keywords = request.query_params.get('keywords', '')
        create_time = request.query_params.get('createTime', '')
        page_num = request.query_params.get('pageNum', '1')
        page_size = request.query_params.get('pageSize', '10')
        
        # 转换页码和每页记录数为整数
        try:
            page_num = int(page_num)
            page_size = int(page_size)
            # 边界检查
            if page_num < 1:
                page_num = 1
            if page_size < 1:
                page_size = 10
        except ValueError:
            return Response({
                "code": "A0400",
                "msg": "页码或每页记录数格式不正确"
            }, status=400)
        
        # 构建查询条件
        query = Q(is_deleted=0)
        
        # 关键字过滤（多字段匹配）
        if keywords:
            query &= (
                Q(content__icontains=keywords) |
                Q(request_uri__icontains=keywords) |
                Q(method__icontains=keywords) |
                Q(province__icontains=keywords) |
                Q(city__icontains=keywords) |
                Q(browser__icontains=keywords) |
                Q(os__icontains=keywords)
            )
        
        # 创建时间范围过滤
        if create_time:
            time_parts = create_time.split(',')
            if len(time_parts) == 2:
                start_time, end_time = time_parts
                if start_time:
                    try:
                        start_date = timezone.make_aware(datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S'))
                        query &= Q(create_time__gte=start_date)
                    except ValueError:
                        pass
                if end_time:
                    try:
                        end_date = timezone.make_aware(datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S'))
                        query &= Q(create_time__lte=end_date)
                    except ValueError:
                        pass
        
        # 查询日志并按创建时间倒序排序
        logs = Log.objects.filter(query).order_by('-create_time')
        
        # 获取总记录数
        total = logs.count()
        
        # 计算分页偏移
        offset = (page_num - 1) * page_size
        paginated_logs = logs[offset:offset + page_size]
        
        # 序列化日志数据
        serializer = LogPageSerializer(paginated_logs, many=True)
        
        # 返回分页结果
        return Response({
            "code": "00000",
            "data": {
                "list": serializer.data,
                "total": total
            },
            "msg": "一切ok"
        })


class LogVisitTrendView(APIView):
    """访问趋势统计视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    def get(self, request, *args, **kwargs):
        """
        获取访问趋势统计
        
        查询参数:
        - startDate: 开始日期（必需，格式：yyyy-MM-dd）
        - endDate: 结束日期（必需，格式：yyyy-MM-dd）
        """
        # 获取查询参数
        start_date_str = request.query_params.get('startDate', '')
        end_date_str = request.query_params.get('endDate', '')
        
        # 参数校验
        if not start_date_str or not end_date_str:
            return Response({
                "code": "A0400",
                "msg": "开始日期和结束日期不能为空"
            }, status=400)
        
        try:
            # 使用timezone.make_aware确保datetime对象包含时区信息
            start_date = timezone.make_aware(datetime.strptime(start_date_str, '%Y-%m-%d'))
            end_date = timezone.make_aware(datetime.strptime(end_date_str, '%Y-%m-%d'))
            # 截止日期加1天，以包含当天全部数据
            end_date = end_date + timedelta(days=1)
        except ValueError:
            return Response({
                "code": "A0400",
                "msg": "日期格式不正确，请使用yyyy-MM-dd格式"
            }, status=400)
        
        if start_date > end_date - timedelta(days=1):
            return Response({
                "code": "A0400",
                "msg": "开始日期不能晚于结束日期"
            }, status=400)
        
        # 生成连续的日期列表
        current_date = start_date
        date_list = []
        while current_date < end_date:
            date_list.append(current_date.strftime('%Y-%m-%d'))
            current_date += timedelta(days=1)
        
        # 查询PV数据：每日的日志总数
        pv_data = Log.objects.filter(
            create_time__gte=start_date,
            create_time__lt=end_date,
            is_deleted=0
        ).annotate(
            date=TruncDate('create_time')
        ).values('date').annotate(
            count=Count('id')
        ).order_by('date')
        
        # 查询IP数据：每日的不同IP数量
        ip_data = Log.objects.filter(
            create_time__gte=start_date,
            create_time__lt=end_date,
            is_deleted=0
        ).annotate(
            date=TruncDate('create_time')
        ).values('date').annotate(
            count=Count('ip', distinct=True)
        ).order_by('date')
        
        # 将查询结果转换为字典，方便按日期查找
        pv_dict = {item['date'].strftime('%Y-%m-%d'): item['count'] for item in pv_data}
        ip_dict = {item['date'].strftime('%Y-%m-%d'): item['count'] for item in ip_data}
        
        # 组装最终数据（保证每一天都有数据，没有数据的日期填充0）
        pv_list = [pv_dict.get(date, 0) for date in date_list]
        ip_list = [ip_dict.get(date, 0) for date in date_list]
        
        # 返回结果
        return Response({
            "code": "00000",
            "data": {
                "dates": date_list,
                "pvList": pv_list,
                "ipList": ip_list
            },
            "msg": "一切ok"
        })


class LogVisitStatsView(APIView):
    """访问统计视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    def get(self, request, *args, **kwargs):
        """
        获取访问统计数据
        
        返回今日和累计的UV、PV数据及增长率
        """
        # 获取当前日期时间
        now = timezone.now()
        today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
        today_end = today_start + timedelta(days=1)
        
        # 获取昨天的日期范围
        yesterday_start = today_start - timedelta(days=1)
        yesterday_end = today_start
        
        # 查询今日PV数量
        today_pv_count = Log.objects.filter(
            create_time__gte=today_start,
            create_time__lt=today_end,
            is_deleted=0
        ).count()
        
        # 查询今日UV数量（独立IP）
        today_uv_count = Log.objects.filter(
            create_time__gte=today_start,
            create_time__lt=today_end,
            is_deleted=0
        ).values('ip').distinct().count()
        
        # 查询昨日PV数量
        yesterday_pv_count = Log.objects.filter(
            create_time__gte=yesterday_start,
            create_time__lt=yesterday_end,
            is_deleted=0
        ).count()
        
        # 查询昨日UV数量
        yesterday_uv_count = Log.objects.filter(
            create_time__gte=yesterday_start,
            create_time__lt=yesterday_end,
            is_deleted=0
        ).values('ip').distinct().count()
        
        # 查询总PV数量
        total_pv_count = Log.objects.filter(is_deleted=0).count()
        
        # 查询总UV数量
        total_uv_count = Log.objects.filter(is_deleted=0).values('ip').distinct().count()
        
        # 计算增长率
        pv_growth_rate = 0
        if yesterday_pv_count > 0:
            pv_growth_rate = round((today_pv_count - yesterday_pv_count) / yesterday_pv_count * 100, 2)
        
        uv_growth_rate = 0
        if yesterday_uv_count > 0:
            uv_growth_rate = round((today_uv_count - yesterday_uv_count) / yesterday_uv_count * 100, 2)
        
        # 返回统计结果
        return Response({
            "code": "00000",
            "data": {
                "todayUvCount": today_uv_count,
                "totalUvCount": total_uv_count,
                "uvGrowthRate": uv_growth_rate,
                "todayPvCount": today_pv_count,
                "totalPvCount": total_pv_count,
                "pvGrowthRate": pv_growth_rate
            },
            "msg": "一切ok"
        })
